<template>
	<vxe-modal id='userMaintainAddModal' v-bind='modalConfig' @close='closeModal'>
		<template v-slot:title>
			<a>
				{{ modalConfig['title'] }}
			</a>
		</template>
		<n-scrollbar trigger='hover'>
			<n-form ref='formRef' v-bind='formConfig'
					:model='formData' :rules='formRules'>
				<n-grid :x-gap='24' :cols='2'>
					<n-form-item-grid-item label='用户名' path='userName'>
						<n-input v-model:value='formData["userName"]'
								 :loading='formDataIsReady' type='text'
								 disabled clearable/>
					</n-form-item-grid-item>
					<n-form-item-grid-item label='姓名' path='nickName'>
						<n-input v-model:value='formData["nickName"]'
								 :loading='formDataIsReady' type='text'
								 clearable/>
					</n-form-item-grid-item>
					<n-form-item-grid-item label='手机号码' path='phone'>
						<n-input v-model:value='formData["phone"]'
								 :loading='formDataIsReady' type='text'
								 clearable/>
					</n-form-item-grid-item>
					<n-form-item-grid-item label='邮箱' path='email'>
						<n-input v-model:value='formData["email"]'
								 :loading='formDataIsReady' type='text'
								 clearable/>
					</n-form-item-grid-item>
					<n-form-item-grid-item label='地址' path='address'>
						<n-input v-model:value='formData["address"]'
								 :loading='formDataIsReady' type='text'
								 clearable/>
					</n-form-item-grid-item>
					<n-form-item-grid-item label='身份证号' path='idCard'>
						<n-input v-model:value='formData["idCard"]'
								 :loading='formDataIsReady' type='text'
								 clearable/>
					</n-form-item-grid-item>
					<n-form-item-grid-item label='账号状态' path='status'>
						<n-switch v-model:value='formData.status as string' size='large'
								  :checkedValue='true'
								  :uncheckedValue='false'>
							<template v-slot:checked>启用</template>
							<template v-slot:unchecked>禁用</template>
						</n-switch>
					</n-form-item-grid-item>
					<n-form-item-grid-item label='归属部门' path='deptList'>
						<n-select v-model:value='formData.deptList'
								  :loading='formDataIsReady'
								  :options='options.deptList.list as Array<SelectOption>'
								  multiple filterable
								  virtual-scroll clearable>
						</n-select>
					</n-form-item-grid-item>
					<n-form-item-grid-item label='角色' path='roleList'>
						<n-select v-model:value='formData.roleList'
								  :loading='formDataIsReady'
								  :options='options.roleList.list as Array<SelectOption>'
								  filterable multiple clearable>
						</n-select>
					</n-form-item-grid-item>
					<n-form-item-grid-item label='排序' path='roleList'>
						<n-input-number v-model:value='formData.sort'
										:loading='formDataIsReady'
										style='width:100%;' clearable/>
					</n-form-item-grid-item>
					<n-form-item-grid-item span='2' path='remark' label='备注'>
						<n-input v-model:value='formData["remark"]'
								 :loading='formDataIsReady' type='textarea'
								 :autosize='{minRows:3,maxRows:3}' clearable
								 maxlength='200' show-word-count/>
					</n-form-item-grid-item>
					<n-form-item-grid-item span='2'>
						<n-flex justify='center' style='width:100%;'>
							<n-button type='primary' @click='submitEvent' :loading='formDataIsReady'>
								提交
							</n-button>
							<n-button type='info' @click='clearData' :loading='formDataIsReady'>
								重置
							</n-button>
						</n-flex>
					</n-form-item-grid-item>
				</n-grid>
			</n-form>
		</n-scrollbar>
	</vxe-modal>
</template>
<script lang='ts' setup>
import { onBeforeMount, onMounted, PropType, reactive, ref } from 'vue';
// axios
import axios from '@/config/axios/index.ts';
// 模态框和打印组件
import { VxeModal, VxeUI } from '@/config/vxe/index.ts';
// 字典组件
import type { Dict } from '#/Dictionary.d.ts';
import { VxeModalProps } from 'vxe-table';
import { FormInst, FormItemRule, FormProps, FormRules, FormValidationError, SelectOption } from 'naive-ui';
import type { JsonResultProps } from '#/JsonResult.d.ts';
import type { UserFormDataProps } from '#/User.d.ts';
import type { Options } from '#/Options.d.ts';
// 接收的参数
const props = defineProps({
	params    : {
		type    : Object,
		require : false,
		default : null
	},
	initTable : {
		type    : Function,
		require : true,
		default : null
	},
	dict      : {
		type    : Object as PropType<Dict>,
		require : true,
		default : null
	},
	options   : {
		type    : Object as PropType<Options>,
		require : true,
		default : null
	}
});
// 模态框的配置
const modalConfig = reactive<VxeModalProps>({
	modelValue : false,
	title      : '',
	width      : '',
	height     : '',
	showClose  : true,
	resize     : true
});
// 表单配置
const formConfig = reactive<FormProps>({
	labelWidth           : 'auto',
	labelAlign           : 'left',
	labelPlacement       : 'left',
	size                 : 'medium',
	requireMarkPlacement : 'right-hanging'
});
// 表单绑定数据
const formDataIsReady = ref<boolean>(true);
const formData = reactive<UserFormDataProps>({
	tenantCode : sessionStorage.getItem('loginTenantCode'),
	userType   : 'browser_user',
	userName   : null,
	nickName   : null,
	idCard     : null,
	email      : null,
	phone      : null,
	address    : null,
	status     : null,
	remark     : null,
	sort       : null,
	deptList   : [],
	roleList   : []
});
const currentData = reactive<UserFormDataProps>({
	tenantCode : sessionStorage.getItem('loginTenantCode'),
	userType   : 'browser_user',
	userName   : null,
	nickName   : null,
	idCard     : null,
	email      : null,
	phone      : null,
	address    : null,
	status     : null,
	remark     : null,
	sort       : null,
	deptList   : [],
	roleList   : []
});
// 表单校验规则
const formRules = reactive<FormRules>({
	userName : {
		required : true,
		trigger  : ['input', 'blur'],
		message  : '请输入用户名'
	},
	status   : {
		required : true,
		type     : 'boolean',
		trigger  : ['input', 'blur'],
		message  : '请选择账号状态'
	},
	nickName : {
		required : true,
		trigger  : ['input', 'blur'],
		message  : '请输入昵称'
	},
	address  : {
		required : false
	},
	email    : {
		required : false,
		trigger  : ['input', 'blur'],
		validator(rule: FormItemRule, value: any) {
			return new Promise<void>((resolve, reject) => {
				// 如果没填写任何字符,那就不检测
				if (!value) {
					resolve();
				}
				const regExp = /^\w+@[a-z0-9]+\.[a-z]{2,4}$/;
				if (!regExp.test(value)) {
					reject(Error('邮箱格式不对'));
				}
				resolve();
			});
		}
	},
	phone    : {
		required : false,
		trigger  : ['input', 'blur'],
		validator(rule: FormItemRule, value: any) {
			return new Promise<void>((resolve, reject) => {
				// 没有填写,那就不管,直接通过
				if (!value) {
					resolve();
				}
				// 检查是否满足11位
				if (11 !== value.length) {
					reject(Error('长度是11个数字'));
				}
				// 没有任何问题就检测通过
				resolve();
			});
		}
	},
	idCard   : {
		required : true,
		trigger  : ['input', 'blur'],
		validator(rule: FormItemRule, value: any) {
			return new Promise<void>((resolve, reject) => {
				// 身份证是必输项,不存在则不通过
				if (!value) {
					reject(Error('请输入身份证号'));
				}
				// 新一代的身份证是18位的,位数不足则不通过
				if (18 !== value.length) {
					reject(Error('长度是18个字符'));
				}
				// 没有检测出问题则通过
				resolve();
			});
		}
	},
	remark   : {
		required : false
	},
	deptList : {
		required : true,
		type     : 'array',
		trigger  : ['input', 'blur'],
		message  : '请选择归属部门'
	},
	roleList : {
		required : false,
		type     : 'array'
	}
});
const formRef = ref<FormInst>();
onBeforeMount(() => {
	// initAll();
});
onMounted(() => {
	// 加载字典
	/*loadDict(['userStatus', 'userRole', 'shortDept']).then((jsonResult: Dict | void) => {
	 // 合并字典
	 Object.assign(dict, jsonResult);
	 });*/
});
const initAll = async () => {
};
const refresh = async () => {
	formDataIsReady.value = true;
	axios<any, JsonResultProps<any>, any>({
		method : 'GET',
		url    : `/user/userDetail/${currentData.tenantCode}/${currentData.userName}`,
		data   : formData
	}).then((jsonResult: JsonResultProps<any>) => {
		if (jsonResult['status']) {
			// 数据填充
			Object.assign(formData, jsonResult.data);
			formDataIsReady.value = false;
		} else {
			VxeUI.modal.message({
				content : jsonResult['msg'],
				status  : 'warning',
				id      : 'failedMessage'
			});
		}
	}).catch((error: unknown) => {
		console.error(error);
		VxeUI.modal.message({
			content : '系统异常,请稍后再试',
			status  : 'error',
			id      : 'errorMessage'
		});
	});
};
const showModal = (row: any) => {
	resetEvent();
	Object.assign(currentData, row);
	refresh();
	// 打开模态框
	Object.assign(modalConfig, {
		modelValue : true,
		height     : '500',
		width      : '700',
		title      : '编辑',
		showClose  : true
	});
};
const closeModal = () => {
	resetEvent();
	Object.assign(modalConfig,
		{
			modelValue : false,
			height     : '500',
			width      : '700',
			title      : '编辑',
			showClose  : true
		});
};
const resetEvent = () => {
	// 清理表单数据
	Object.assign(formData, {
		tenantCode : sessionStorage.getItem('loginTenantCode'),
		userType   : 'browser_user',
		userName   : null,
		nickName   : null,
		idCard     : null,
		email      : null,
		phone      : null,
		address    : null,
		status     : null,
		remark     : null,
		sort       : null,
		deptList   : [],
		roleList   : []
	});
	// 去除表单校验提示
	formRef.value?.restoreValidation();
};
const clearData = () => {
	resetEvent();
	refresh();
};
const submitEvent = () => {
	// 校验菜单
	formRef.value?.validate((errors?: Array<FormValidationError>): void => {
		if (errors) {
			VxeUI.modal.message({ content : '请先完善填写的内容!', status : 'warning', id : 'validateMessage' });
		} else {
			// 提交数据
			axios<any, JsonResultProps<any>, any>({
				method : 'PUT',
				url    : '/user/modify',
				data   : formData
			}).then((jsonResult: JsonResultProps<any>) => {
				if (jsonResult['status']) {
					// 提示用户
					VxeUI.modal.message({
						content : jsonResult['msg'],
						status  : 'success',
						id      : 'successMessage'
					});
					// 刷新数据
					props.initTable();
					closeModal();
				} else {
					VxeUI.modal.message({
						content : jsonResult['msg'],
						status  : 'warning',
						id      : 'failedMessage'
					});
				}
			}).catch((error: unknown) => {
				console.error(error);
				VxeUI.modal.message({
					content : '系统异常,请稍后再试',
					status  : 'error',
					id      : 'errorMessage'
				});
			});
		}
	});
};
// 导出方法
defineExpose({ showModal });
</script>